 (************************************************************************)
 (*  Copyright(c) Filip Lundeholm 2010                                   *)
 (*          All Rights Reserved                                         *)
 (*                                                                      *)
 (************************************************************************)

 program basicdemo;

{$mode objfpc}{$H+}

uses
  Math, SysUtils,psopas;

type
  TBasicDemo = class
  private
    pso: TPSO;
    x:   double;
    function fitnessFunction: double;
  public
    procedure run();
  end;

  // This is the fitness function. It must return a higher
  // value if "better", hence we return the negative function
  // value because we want to minimize the function.
  //
  // Visit this link to see a plot of the function:
  // http://www.wolframalpha.com/input/?i=min+42x^4-33x^3-157x^2%2B22x%2B60
  function TBasicDemo.fitnessFunction(): double;
  var
    temp: double;
  begin
    temp := 42 * (x ** 4) - 33 * (x ** 3) - 157 * (x ** 2) + 22 * x + 60;
    Result := -temp;
  end;

  procedure TBasicDemo.run();
  begin
    writeln('Use psopas to find minimum of the function');
    writeln(' f(x) = 42*x^4 - 33*x^3 - 157*x^2 + 22*x + 60');
    writeln('in the range [-1000, 1000].');
    writeln('');

    //1. Create TPSO instance with the fitness function as parameter.
    pso := TPSO.Create(@fitnessFunction);

    //2. Add variables that should be optimized and their allowed range.
    pso.add(x, -1000, 1000);

    //3. Optimize with default number of swarm iterations.
    pso.optimize();

    writeln('Minimum found at x='+floattostr(x));
    writeln('(true minimum at x=1.66475243585021)');
    writeln('');
    writeln('Press a key to continue');
    readln;
  end;

var
  dummy: TBasicDemo;
begin
  dummy := TBasicDemo.Create;
  dummy.run;
end.

